Skip to content

agent: @U0AJM7X8FBR read the mono repo, then ULTRATHINK about our non-technical#14

Open
sweetmantech wants to merge 1 commit intomainfrom
agent/-u0ajm7x8fbr-read-the-mono-rep-1773414900764
Open

agent: @U0AJM7X8FBR read the mono repo, then ULTRATHINK about our non-technical#14
sweetmantech wants to merge 1 commit intomainfrom
agent/-u0ajm7x8fbr-read-the-mono-rep-1773414900764

Conversation

@sweetmantech
Copy link
Copy Markdown

@sweetmantech sweetmantech commented Mar 13, 2026

Automated PR from coding agent.

Summary by CodeRabbit

  • New Features

    • Added reset command capability to clear message history in the agent terminal.
  • Bug Fixes

    • Fixed configuration syntax issue in build configuration.
    • Added missing authorization headers for sandbox API requests.
  • Documentation

    • Added comprehensive JSDoc comments across the codebase for improved clarity and maintainability.

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bash Ready Ready Preview Mar 13, 2026 3:19pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 13, 2026

📝 Walkthrough

Walkthrough

This PR adds comprehensive JSDoc documentation across multiple codebase files, performs code formatting refinements (consolidating multi-line expressions to single-line equivalents), introduces a reset command to the agent command flow, adds Bearer token authentication to a sandbox setup API call, and fixes a syntax issue in the Next.js configuration file.

Changes

Cohort / File(s) Summary
Terminal Components Documentation
app/components/lite-terminal/LiteTerminal.ts, app/components/lite-terminal/ansi-parser.ts, app/components/lite-terminal/input-handler.ts, app/components/lite-terminal/index.ts
Added JSDoc documentation blocks to methods and functions; refactored arrow function parameter syntax; consolidated multi-line object literals and style assignments to single-line forms; minor spacing adjustments without altering runtime behavior.
Agent & Terminal UI Components
app/components/terminal-parts/agent-command.ts, app/components/terminal-parts/commands.ts, app/components/terminal-parts/input-handler.ts, app/components/terminal-parts/markdown.ts, app/components/terminal-parts/welcome.ts
Added JSDoc documentation; implemented reset command for message history clearing; refactored arrow function parameter syntax; minor formatting adjustments to string literals and multi-line argument lists.
API Routes & Request Handlers
app/api/agent/new/route.ts, app/api/agent/route.ts, app/api/fs/route.ts
Added JSDoc documentation for exported POST functions; consolidated arrow function definitions to single-line format; minor formatting adjustments with no change to runtime behavior.
Sandbox & API Library Functions
lib/sandbox/createFreshSandbox.ts, lib/sandbox/createSnapshotSandbox.ts, lib/sandbox/readSourceFiles.ts, lib/sandbox/saveSnapshot.ts, lib/recoup-api/createSandbox.ts, lib/recoup-api/getSandboxes.ts, lib/recoup-api/setupSandbox.ts, lib/recoup-api/updateAccountSnapshot.ts, lib/agent/createAgentResponse.ts, lib/agent/handleAgentRequest.ts
Added JSDoc documentation blocks documenting parameters; consolidated multi-line function signatures to single-line format; added Bearer token authorization header to setupSandbox API call.
Route & Hook Configuration
app/md/[[...path]]/route.ts, app/hooks/useSetupSandbox.ts
Added JSDoc documentation; changed LICENSE key from quoted string to unquoted identifier in FILES mapping; reformatted 404 Response body with improved readability.
Configuration Fix
next.config.ts
Fixed syntax error in rewrites property by replacing semicolon with trailing comma to properly separate object properties.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 Whiskers twitch with pride so true,
JSDoc comments, fresh and new,
Code so neat, no line in sight,
Rabbit's work makes syntax bright,
Reset button, auth so clean—
Best refactored I have seen! 🐇✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title references a user ID and vague terms like 'ULTRATHINK' and 'non-technical' without clearly describing the actual changes made to the codebase. Replace with a clear, descriptive title that summarizes the main changes, such as 'docs: add JSDoc comments and minor formatting improvements across multiple modules'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch agent/-u0ajm7x8fbr-read-the-mono-rep-1773414900764
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/terminal-parts/agent-command.ts (1)

112-142: ⚠️ Potential issue | 🟠 Major

Don’t let the generic Thinking... timer run while reasoning text is already streaming.

reasoning-start currently re-arms the placeholder timer, and reasoning-delta keeps resetting it. A 500ms pause will inject Thinking... into the live reasoning line, and the later \r\x1b[K clear can wipe that whole line.

Suggested fix
       const showThinking = () => {
+        if (isStreaming) {
+          return;
+        }
         if (!showingThinking) {
           showingThinking = true;
           term.write("\x1b[2mThinking...\x1b[0m");
         }
       };
@@
             else if (data.type === "reasoning-start") {
-              clearThinking(); // Clear "Thinking..." before actual reasoning
+              clearThinking(false); // stop the placeholder while reasoning streams
               // Start streaming thinking in dim italic
               isStreaming = true;
               term.write("\x1b[2m\x1b[3m"); // dim + italic
             } else if (data.type === "reasoning-delta" && data.delta) {
               // Stream thinking tokens as they arrive
               term.write(formatForTerminal(data.delta));
-              resetThinkingTimer(); // Keep resetting while actively streaming
             } else if (data.type === "reasoning-end") {
               // End thinking block
               if (isStreaming) {
                 term.write("\x1b[0m\r\n"); // reset styling + newline
                 isStreaming = false;
+                resetThinkingTimer();
               }
             }

Also applies to: 276-289

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/agent-command.ts` around lines 112 - 142, The
placeholder timer is being rearmed while live reasoning text is streaming, which
causes "Thinking..." to be injected into the same line and then wiped; modify
the logic so that when streaming reasoning is active you never start or reset
the thinking timer: in the handlers referenced as reasoning-start and
reasoning-delta stop calling resetThinkingTimer or starting thinkingTimeout when
showingThinking is true or when a stream-active flag is set, and update
resetThinkingTimer, showThinking, and clearThinking to check the
showingThinking/streaming state (use the existing showingThinking and
thinkingTimeout symbols) so resetThinkingTimer is a no-op while streaming and
showThinking is only scheduled when not streaming; ensure clearThinking does not
restart the timer if the restart is triggered due to active streaming.
🧹 Nitpick comments (12)
app/components/terminal-parts/welcome.ts (1)

9-12: Incomplete JSDoc adds no value.

The JSDoc has an empty description and @param term lacks any explanation. Either complete it with meaningful documentation or remove it entirely.

📝 Suggested complete JSDoc
-/**
- *
- * `@param` term
- */
+/**
+ * Displays the welcome message and ASCII art in the terminal.
+ * `@param` term - The terminal instance to write the welcome output to.
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/welcome.ts` around lines 9 - 12, The JSDoc
block above the function that accepts the parameter "term" is empty and should
be either removed or replaced with a concise doc comment: add a brief
description of what the function does, a clear `@param` term line describing the
parameter's expected type and role (e.g., terminal instance or DOM element used
to render output), and an `@returns` tag if the function returns a value;
alternatively delete the entire JSDoc if no documentation is needed. Target the
JSDoc immediately preceding the function that takes "term" (the function in this
file that uses the term parameter) and ensure the comment accurately reflects
the function signature and behavior.
app/components/terminal-parts/agent-command.ts (1)

16-29: These JSDoc blocks are still placeholders.

They only restate parameter names, so they add maintenance cost without documenting behavior. Either describe the newline normalization / command contract here, or drop the blocks and rely on the existing type signatures.

As per coding guidelines, "Apply KISS (Keep It Simple) - prefer simple solutions over clever ones" and "Apply YAGNI - don't build for hypothetical future needs."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/agent-command.ts` around lines 16 - 29, The
JSDoc blocks for formatForTerminal (and the surrounding terminal-related
functions) are placeholders that only restate parameter names; either remove the
empty JSDoc comments or replace them with a concise, accurate description of
behavior — e.g., for formatForTerminal state that it normalizes tabs to two
spaces and normalizes newlines to CRLF ("\r\n") for terminal compatibility and
describe the expected input/return contract — and ensure the comment is attached
to the function name formatForTerminal (and the subsequent agent terminal
functions) so the codebase contains meaningful, minimal docs rather than
redundant parameter lists.
app/components/terminal-parts/commands.ts (1)

4-6: Remove placeholder JSDoc or make it meaningful.

This block is empty and adds noise; either delete it or document intent/return shape.

♻️ Suggested cleanup
-/**
- *
- */
 export function createStaticCommands() {

As per coding guidelines, "Apply KISS (Keep It Simple) - prefer simple solutions over clever ones."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/commands.ts` around lines 4 - 6, Remove the
empty placeholder JSDoc block at the top of the module (the empty /** ... */
comment in app/components/terminal-parts/commands.ts) or replace it with a
concise meaningful comment describing the module's purpose and exported shapes
(e.g., what key functions/commands return). Keep it short and precise to satisfy
KISS—either delete the block entirely or document intent/return shapes for the
module's exported symbols.
app/components/lite-terminal/input-handler.ts (1)

186-188: Empty JSDoc block on private method adds noise.

The empty JSDoc block for scrollCursorIntoView provides no information. For private methods, either add a meaningful description or omit the JSDoc entirely.

📝 Suggested fix
-  /**
-   *
-   */
   private scrollCursorIntoView(): void {

Or add a description:

-  /**
-   *
-   */
+  /** Scrolls the terminal cursor element into view */
   private scrollCursorIntoView(): void {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/lite-terminal/input-handler.ts` around lines 186 - 188, The
empty JSDoc above the private method scrollCursorIntoView adds noise; either
remove the entire empty comment block or replace it with a concise description
of what scrollCursorIntoView does (and document any parameters/return value if
applicable) so the JSDoc is meaningful—locate the private method named
scrollCursorIntoView in input-handler.ts and either delete the /** */ block or
add a one-line summary and param/return tags matching the method signature.
lib/sandbox/createSnapshotSandbox.ts (1)

5-9: JSDoc comment is incomplete.

The parameters lack descriptions. Documenting the fallback behavior would be particularly valuable for this function.

📝 Suggested improvement
-/**
- *
- * `@param` bearerToken
- * `@param` agentDataDir
- */
+/**
+ * Retrieves an existing sandbox from a snapshot, or creates a fresh one if unavailable.
+ *
+ * `@param` bearerToken - Authentication token for the Recoup API
+ * `@param` agentDataDir - Directory containing agent data to initialize fresh sandboxes
+ * `@returns` A Sandbox instance, either restored from snapshot or newly created
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/sandbox/createSnapshotSandbox.ts` around lines 5 - 9, Add full JSDoc for
the createSnapshotSandbox function: document each parameter (bearerToken: string
— what it represents and when it can be omitted or empty; agentDataDir: string —
path where agent data is stored and its default/fallback if not provided),
describe return type and any thrown errors, and explicitly state the fallback
behavior (e.g., what directory is used or how bearerToken is
sourced/fallbacked). Reference the createSnapshotSandbox function and its
parameters bearerToken and agentDataDir so reviewers can verify the docs match
implementation and edge cases.
app/api/agent/new/route.ts (1)

5-8: JSDoc comment is incomplete.

Same pattern as other files - parameter listed without description.

📝 Suggested improvement
-/**
- *
- * `@param` req
- */
+/**
+ * Creates a new agent session with a fresh sandbox environment.
+ *
+ * `@param` req - The incoming request with Authorization header and messages
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/agent/new/route.ts` around lines 5 - 8, The JSDoc above the handler
is incomplete — update the comment to describe the function's purpose and its
parameters/return: add a brief description for the req parameter (e.g., type,
expected shape or fields used), document the return value (e.g., Response or
JSON payload), and include any thrown errors or side effects; target the JSDoc
block that currently only lists "@param req" in app/api/agent/new/route.ts so
callers and maintainers can understand what the handler expects and returns.
app/components/terminal-parts/markdown.ts (1)

13-14: JSDoc parameter lacks description.

The @param text annotation would be more useful with a description explaining what kind of text is expected (e.g., markdown-formatted string).

📝 Suggested improvement
  * Preserves the actual characters but wraps them in ANSI escape sequences.
- *
- * `@param` text
+ *
+ * `@param` text - The markdown-formatted text to apply terminal styling to
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/markdown.ts` around lines 13 - 14, Update the
JSDoc for the function in app/components/terminal-parts/markdown.ts by adding a
descriptive sentence to the `@param` text annotation (e.g., "text -
markdown-formatted string to be rendered" or similar) so callers know the
expected input format and purpose; locate the JSDoc block that currently
contains "@param text" and replace it with a concise description referencing the
markdown-formatted input used by the function that processes or renders the
markdown (the parameter named text).
lib/agent/createAgentResponse.ts (1)

8-13: JSDoc comment is incomplete.

The JSDoc block lists parameter names but lacks descriptions, return type documentation, and a function description. This provides minimal value over no documentation at all.

📝 Suggested improvement
-/**
- *
- * `@param` sandbox
- * `@param` messages
- * `@param` bearerToken
- */
+/**
+ * Creates a streaming agent response using the provided sandbox environment.
+ *
+ * `@param` sandbox - The Vercel sandbox instance to execute commands in
+ * `@param` messages - Array of conversation messages to process
+ * `@param` bearerToken - Authentication token for saving snapshots
+ * `@returns` A streaming Response object
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/agent/createAgentResponse.ts` around lines 8 - 13, The JSDoc for the
createAgentResponse function is incomplete; update the comment block above
createAgentResponse to include a one-line function description, descriptive
`@param` tags for sandbox, messages, and bearerToken (including expected types and
whether optional), and an `@returns` tag describing the returned value/type (and
any promise/async behavior). Also document any thrown errors or side effects
(e.g., network calls) if applicable so callers know what to expect.
lib/agent/handleAgentRequest.ts (1)

6-10: JSDoc comment is incomplete.

Same issue as other files - the JSDoc block lists parameters without descriptions. Consider adding meaningful documentation or removing the empty block.

📝 Suggested improvement
-/**
- *
- * `@param` req
- * `@param` createSandbox
- */
+/**
+ * Handles an incoming agent request by validating auth and delegating to the agent response creator.
+ *
+ * `@param` req - The incoming HTTP request with Authorization header and messages body
+ * `@param` createSandbox - Factory function to create a sandbox instance
+ * `@returns` A streaming Response from the agent
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/agent/handleAgentRequest.ts` around lines 6 - 10, Update the incomplete
JSDoc for the handleAgentRequest function by either removing the empty block or
adding meaningful descriptions for the parameters and return value: document the
req parameter (type and purpose), the createSandbox parameter (what it
does/expected type), and the function's return value or thrown errors; locate
the JSDoc immediately above the handleAgentRequest function in
lib/agent/handleAgentRequest.ts and ensure the annotations (`@param` req, `@param`
createSandbox, and `@returns` or `@throws`) accurately describe expected types and
behavior.
app/api/fs/route.ts (1)

90-93: Empty JSDoc block adds no value.

The JSDoc block for GET is completely empty with no description or documentation. Either add meaningful documentation or remove the empty block entirely.

📝 Suggested fix
-/**
- *
- */
+/**
+ * Returns all text files from the agent data directory as a JSON map.
+ */
 export async function GET() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/fs/route.ts` around lines 90 - 93, The empty JSDoc block above the
exported GET function is noise; either delete the empty /** */ block or replace
it with a concise description of what GET does (inputs, output shape, status
codes) so the route handler GET is documented; update the comment immediately
above the GET declaration accordingly.
lib/sandbox/readSourceFiles.ts (1)

5-9: JSDoc comment is incomplete.

The parameters dir and baseDir lack descriptions explaining their purpose. The optional nature of baseDir and its relationship to dir should be documented.

📝 Suggested improvement
-/**
- *
- * `@param` dir
- * `@param` baseDir
- */
+/**
+ * Recursively reads all source files from a directory, excluding node_modules and .git.
+ *
+ * `@param` dir - The directory to read files from
+ * `@param` baseDir - Base directory for computing relative paths (defaults to dir)
+ * `@returns` Array of file objects with sandbox-relative paths and content buffers
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/sandbox/readSourceFiles.ts` around lines 5 - 9, The JSDoc for
readSourceFiles is incomplete: add descriptive `@param` tags for dir and baseDir
(noting baseDir is optional) and explain their relationship (e.g., dir is the
path to scan for source files and baseDir, if provided, is used to compute
relative paths or as the root for normalization); update the function-level
comment above readSourceFiles to clearly document return value and optional
parameters so callers understand how baseDir alters the produced paths.
app/md/[[...path]]/route.ts (1)

20-33: SRP guideline violation: two exported functions in one file.
generateStaticParams and GET are both exported from this module. Please refactor to one exported function per file, or add an explicit exception for this framework-specific route file to keep guideline enforcement consistent.

As per coding guidelines, **/*.{js,ts,jsx,tsx}: Apply SRP (Single Responsibility Principle) - one exported function per file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/md/`[[...path]]/route.ts around lines 20 - 33, This file exports both
generateStaticParams and GET which violates the SRP rule; fix by moving one
export into its own module or add an explicit rule exception for this framework
route file: either extract generateStaticParams into a separate file (exporting
it from there and updating any imports/route config) or keep both but add a
clear file-level exception comment (or disable the specific linter rule) so the
linter knows this route file is allowed to export both; reference the functions
generateStaticParams and GET when making the change so you update the correct
symbols.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/terminal-parts/agent-command.ts`:
- Around line 293-305: The branches handling stream-level failures (data.type
"error", "abort", and the tool error branches in the same handler and the
similar block at 313-336) currently only write to the terminal and leave
createAgentCommand returning exitCode: 0 with the last user message still
present in agentMessages; update these branches in createAgentCommand to treat
them as failed commands by setting a non-zero exit code (e.g., exitCode = 1),
ensure the command completion/resolution path is invoked (so the promise
returned by createAgentCommand resolves/rejects appropriately), and clean up
agentMessages state (remove the just-added user message or append an assistant
error message) so the conversation doesn't continue from a dangling prompt;
reference the handler that processes data.type values and the createAgentCommand
function to locate where to set exitCode, resolve/reject the command promise,
and update agentMessages.

In `@app/components/terminal-parts/input-handler.ts`:
- Line 73: The history initialization using
JSON.parse(sessionStorage.getItem(HISTORY_KEY) || "[]") can throw if
sessionStorage is unavailable or the stored value is malformed; wrap the
retrieval and parse in a try/catch and fallback to an empty array on any error.
Specifically, update the initialization of the history constant in
input-handler.ts (the line creating history and referencing HISTORY_KEY,
sessionStorage.getItem, and JSON.parse) to safely check for sessionStorage
presence, attempt to read and parse the stored string inside try/catch, and
assign [] when access or parsing fails so input initialization never throws.

In `@app/md/`[[...path]]/route.ts:
- Around line 33-35: In GET, change the mutable declaration of path to an
immutable one since it is never reassigned: replace "let { path } = await
params;" with a const binding (e.g., "const { path } = await params;") in the
GET function so the linter rule prefer-const is satisfied; keep the subsequent
use that builds filePath (filePath = path?.join("/")... || "README.md")
unchanged.

---

Outside diff comments:
In `@app/components/terminal-parts/agent-command.ts`:
- Around line 112-142: The placeholder timer is being rearmed while live
reasoning text is streaming, which causes "Thinking..." to be injected into the
same line and then wiped; modify the logic so that when streaming reasoning is
active you never start or reset the thinking timer: in the handlers referenced
as reasoning-start and reasoning-delta stop calling resetThinkingTimer or
starting thinkingTimeout when showingThinking is true or when a stream-active
flag is set, and update resetThinkingTimer, showThinking, and clearThinking to
check the showingThinking/streaming state (use the existing showingThinking and
thinkingTimeout symbols) so resetThinkingTimer is a no-op while streaming and
showThinking is only scheduled when not streaming; ensure clearThinking does not
restart the timer if the restart is triggered due to active streaming.

---

Nitpick comments:
In `@app/api/agent/new/route.ts`:
- Around line 5-8: The JSDoc above the handler is incomplete — update the
comment to describe the function's purpose and its parameters/return: add a
brief description for the req parameter (e.g., type, expected shape or fields
used), document the return value (e.g., Response or JSON payload), and include
any thrown errors or side effects; target the JSDoc block that currently only
lists "@param req" in app/api/agent/new/route.ts so callers and maintainers can
understand what the handler expects and returns.

In `@app/api/fs/route.ts`:
- Around line 90-93: The empty JSDoc block above the exported GET function is
noise; either delete the empty /** */ block or replace it with a concise
description of what GET does (inputs, output shape, status codes) so the route
handler GET is documented; update the comment immediately above the GET
declaration accordingly.

In `@app/components/lite-terminal/input-handler.ts`:
- Around line 186-188: The empty JSDoc above the private method
scrollCursorIntoView adds noise; either remove the entire empty comment block or
replace it with a concise description of what scrollCursorIntoView does (and
document any parameters/return value if applicable) so the JSDoc is
meaningful—locate the private method named scrollCursorIntoView in
input-handler.ts and either delete the /** */ block or add a one-line summary
and param/return tags matching the method signature.

In `@app/components/terminal-parts/agent-command.ts`:
- Around line 16-29: The JSDoc blocks for formatForTerminal (and the surrounding
terminal-related functions) are placeholders that only restate parameter names;
either remove the empty JSDoc comments or replace them with a concise, accurate
description of behavior — e.g., for formatForTerminal state that it normalizes
tabs to two spaces and normalizes newlines to CRLF ("\r\n") for terminal
compatibility and describe the expected input/return contract — and ensure the
comment is attached to the function name formatForTerminal (and the subsequent
agent terminal functions) so the codebase contains meaningful, minimal docs
rather than redundant parameter lists.

In `@app/components/terminal-parts/commands.ts`:
- Around line 4-6: Remove the empty placeholder JSDoc block at the top of the
module (the empty /** ... */ comment in
app/components/terminal-parts/commands.ts) or replace it with a concise
meaningful comment describing the module's purpose and exported shapes (e.g.,
what key functions/commands return). Keep it short and precise to satisfy
KISS—either delete the block entirely or document intent/return shapes for the
module's exported symbols.

In `@app/components/terminal-parts/markdown.ts`:
- Around line 13-14: Update the JSDoc for the function in
app/components/terminal-parts/markdown.ts by adding a descriptive sentence to
the `@param` text annotation (e.g., "text - markdown-formatted string to be
rendered" or similar) so callers know the expected input format and purpose;
locate the JSDoc block that currently contains "@param text" and replace it with
a concise description referencing the markdown-formatted input used by the
function that processes or renders the markdown (the parameter named text).

In `@app/components/terminal-parts/welcome.ts`:
- Around line 9-12: The JSDoc block above the function that accepts the
parameter "term" is empty and should be either removed or replaced with a
concise doc comment: add a brief description of what the function does, a clear
`@param` term line describing the parameter's expected type and role (e.g.,
terminal instance or DOM element used to render output), and an `@returns` tag if
the function returns a value; alternatively delete the entire JSDoc if no
documentation is needed. Target the JSDoc immediately preceding the function
that takes "term" (the function in this file that uses the term parameter) and
ensure the comment accurately reflects the function signature and behavior.

In `@app/md/`[[...path]]/route.ts:
- Around line 20-33: This file exports both generateStaticParams and GET which
violates the SRP rule; fix by moving one export into its own module or add an
explicit rule exception for this framework route file: either extract
generateStaticParams into a separate file (exporting it from there and updating
any imports/route config) or keep both but add a clear file-level exception
comment (or disable the specific linter rule) so the linter knows this route
file is allowed to export both; reference the functions generateStaticParams and
GET when making the change so you update the correct symbols.

In `@lib/agent/createAgentResponse.ts`:
- Around line 8-13: The JSDoc for the createAgentResponse function is
incomplete; update the comment block above createAgentResponse to include a
one-line function description, descriptive `@param` tags for sandbox, messages,
and bearerToken (including expected types and whether optional), and an `@returns`
tag describing the returned value/type (and any promise/async behavior). Also
document any thrown errors or side effects (e.g., network calls) if applicable
so callers know what to expect.

In `@lib/agent/handleAgentRequest.ts`:
- Around line 6-10: Update the incomplete JSDoc for the handleAgentRequest
function by either removing the empty block or adding meaningful descriptions
for the parameters and return value: document the req parameter (type and
purpose), the createSandbox parameter (what it does/expected type), and the
function's return value or thrown errors; locate the JSDoc immediately above the
handleAgentRequest function in lib/agent/handleAgentRequest.ts and ensure the
annotations (`@param` req, `@param` createSandbox, and `@returns` or `@throws`)
accurately describe expected types and behavior.

In `@lib/sandbox/createSnapshotSandbox.ts`:
- Around line 5-9: Add full JSDoc for the createSnapshotSandbox function:
document each parameter (bearerToken: string — what it represents and when it
can be omitted or empty; agentDataDir: string — path where agent data is stored
and its default/fallback if not provided), describe return type and any thrown
errors, and explicitly state the fallback behavior (e.g., what directory is used
or how bearerToken is sourced/fallbacked). Reference the createSnapshotSandbox
function and its parameters bearerToken and agentDataDir so reviewers can verify
the docs match implementation and edge cases.

In `@lib/sandbox/readSourceFiles.ts`:
- Around line 5-9: The JSDoc for readSourceFiles is incomplete: add descriptive
`@param` tags for dir and baseDir (noting baseDir is optional) and explain their
relationship (e.g., dir is the path to scan for source files and baseDir, if
provided, is used to compute relative paths or as the root for normalization);
update the function-level comment above readSourceFiles to clearly document
return value and optional parameters so callers understand how baseDir alters
the produced paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 017dce40-5e5d-478a-a3fe-80ab22ea3158

📥 Commits

Reviewing files that changed from the base of the PR and between 4f11645 and 901900e.

📒 Files selected for processing (25)
  • app/api/agent/new/route.ts
  • app/api/agent/route.ts
  • app/api/fs/route.ts
  • app/components/lite-terminal/LiteTerminal.ts
  • app/components/lite-terminal/ansi-parser.ts
  • app/components/lite-terminal/index.ts
  • app/components/lite-terminal/input-handler.ts
  • app/components/terminal-parts/agent-command.ts
  • app/components/terminal-parts/commands.ts
  • app/components/terminal-parts/input-handler.ts
  • app/components/terminal-parts/markdown.ts
  • app/components/terminal-parts/welcome.ts
  • app/hooks/useSetupSandbox.ts
  • app/md/[[...path]]/route.ts
  • lib/agent/createAgentResponse.ts
  • lib/agent/handleAgentRequest.ts
  • lib/recoup-api/createSandbox.ts
  • lib/recoup-api/getSandboxes.ts
  • lib/recoup-api/setupSandbox.ts
  • lib/recoup-api/updateAccountSnapshot.ts
  • lib/sandbox/createFreshSandbox.ts
  • lib/sandbox/createSnapshotSandbox.ts
  • lib/sandbox/readSourceFiles.ts
  • lib/sandbox/saveSnapshot.ts
  • next.config.ts

Comment on lines 293 to 305
else if (data.type === "error") {
const errorMsg = data.error || data.message || "Unknown error";
term.write(`\x1b[31mError: ${formatForTerminal(String(errorMsg))}\x1b[0m\r\n`);
}
else if (data.type === "tool-input-error") {
} else if (data.type === "tool-input-error") {
const errorMsg = data.error || "Tool input error";
term.write(`\x1b[31m[Tool Error] ${formatForTerminal(String(errorMsg))}\x1b[0m\r\n`);
}
else if (data.type === "tool-output-error") {
} else if (data.type === "tool-output-error") {
const errorMsg = data.error || "Tool execution error";
term.write(`\x1b[31m[Tool Error] ${formatForTerminal(String(errorMsg))}\x1b[0m\r\n`);
}
else if (data.type === "tool-output-denied") {
} else if (data.type === "tool-output-denied") {
term.write(`\x1b[33m[Tool Denied]\x1b[0m\r\n`);
}
else if (data.type === "abort") {
} else if (data.type === "abort") {
term.write(`\x1b[33m[Aborted]\x1b[0m\r\n`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Treat stream-level error and abort events as failed commands.

Right now those branches only print to the terminal. If the stream then closes, createAgentCommand still returns exitCode: 0 and leaves the just-added user message in agentMessages, so the next turn starts from a dangling prompt with no assistant reply.

Suggested fix
       let isStreaming = false; // Track if we're streaming thinking
+      let fatalStreamError: string | null = null;
@@
-      while (true) {
+      stream: while (true) {
         const { done, value } = await reader.read();
         if (done) break;
@@
             // Handle errors
             else if (data.type === "error") {
-              const errorMsg = data.error || data.message || "Unknown error";
-              term.write(`\x1b[31mError: ${formatForTerminal(String(errorMsg))}\x1b[0m\r\n`);
+              fatalStreamError = String(data.error || data.message || "Unknown error");
+              term.write(`\x1b[31mError: ${formatForTerminal(fatalStreamError)}\x1b[0m\r\n`);
+              await reader.cancel();
+              break stream;
             } else if (data.type === "tool-input-error") {
               const errorMsg = data.error || "Tool input error";
               term.write(`\x1b[31m[Tool Error] ${formatForTerminal(String(errorMsg))}\x1b[0m\r\n`);
             } else if (data.type === "tool-output-error") {
               const errorMsg = data.error || "Tool execution error";
               term.write(`\x1b[31m[Tool Error] ${formatForTerminal(String(errorMsg))}\x1b[0m\r\n`);
             } else if (data.type === "tool-output-denied") {
               term.write(`\x1b[33m[Tool Denied]\x1b[0m\r\n`);
             } else if (data.type === "abort") {
+              fatalStreamError = "Aborted";
               term.write(`\x1b[33m[Aborted]\x1b[0m\r\n`);
+              await reader.cancel();
+              break stream;
             }
@@
       // Clean up thinking timer (don't restart - we're done)
       clearThinking(false);
+
+      if (fatalStreamError) {
+        agentMessages.pop();
+        return {
+          stdout: "",
+          stderr: `Error: ${fatalStreamError}\n`,
+          exitCode: 1,
+        };
+      }

Also applies to: 313-336

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/agent-command.ts` around lines 293 - 305, The
branches handling stream-level failures (data.type "error", "abort", and the
tool error branches in the same handler and the similar block at 313-336)
currently only write to the terminal and leave createAgentCommand returning
exitCode: 0 with the last user message still present in agentMessages; update
these branches in createAgentCommand to treat them as failed commands by setting
a non-zero exit code (e.g., exitCode = 1), ensure the command
completion/resolution path is invoked (so the promise returned by
createAgentCommand resolves/rejects appropriately), and clean up agentMessages
state (remove the just-added user message or append an assistant error message)
so the conversation doesn't continue from a dangling prompt; reference the
handler that processes data.type values and the createAgentCommand function to
locate where to set exitCode, resolve/reject the command promise, and update
agentMessages.

const history: string[] = JSON.parse(
sessionStorage.getItem(HISTORY_KEY) || "[]"
);
const history: string[] = JSON.parse(sessionStorage.getItem(HISTORY_KEY) || "[]");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard history initialization against storage/parse failures.
Line 73 can throw and break input initialization if storage is unavailable or the stored payload is malformed.

Suggested hardening
-  const history: string[] = JSON.parse(sessionStorage.getItem(HISTORY_KEY) || "[]");
+  let history: string[] = [];
+  try {
+    const raw = sessionStorage.getItem(HISTORY_KEY) || "[]";
+    const parsed = JSON.parse(raw);
+    history = Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === "string") : [];
+  } catch {
+    history = [];
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const history: string[] = JSON.parse(sessionStorage.getItem(HISTORY_KEY) || "[]");
let history: string[] = [];
try {
const raw = sessionStorage.getItem(HISTORY_KEY) || "[]";
const parsed = JSON.parse(raw);
history = Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === "string") : [];
} catch {
history = [];
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/terminal-parts/input-handler.ts` at line 73, The history
initialization using JSON.parse(sessionStorage.getItem(HISTORY_KEY) || "[]") can
throw if sessionStorage is unavailable or the stored value is malformed; wrap
the retrieval and parse in a try/catch and fallback to an empty array on any
error. Specifically, update the initialization of the history constant in
input-handler.ts (the line creating history and referencing HISTORY_KEY,
sessionStorage.getItem, and JSON.parse) to safely check for sessionStorage
presence, attempt to read and parse the stored string inside try/catch, and
assign [] when access or parsing fails so input initialization never throws.

Comment on lines +33 to 35
export async function GET(_request: Request, { params }: { params: Promise<{ path?: string[] }> }) {
let { path } = await params;
const filePath = path?.join("/").replace(/^md\//, "") || "README.md";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use const for path to satisfy lint and intent.
Line 34 does not reassign path; keeping let will continue to trigger prefer-const.

Suggested fix
-export async function GET(_request: Request, { params }: { params: Promise<{ path?: string[] }> }) {
-  let { path } = await params;
+export async function GET(_request: Request, { params }: { params: Promise<{ path?: string[] }> }) {
+  const { path } = await params;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function GET(_request: Request, { params }: { params: Promise<{ path?: string[] }> }) {
let { path } = await params;
const filePath = path?.join("/").replace(/^md\//, "") || "README.md";
export async function GET(_request: Request, { params }: { params: Promise<{ path?: string[] }> }) {
const { path } = await params;
const filePath = path?.join("/").replace(/^md\//, "") || "README.md";
🧰 Tools
🪛 ESLint

[error] 34-34: 'path' is never reassigned. Use 'const' instead.

(prefer-const)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/md/`[[...path]]/route.ts around lines 33 - 35, In GET, change the mutable
declaration of path to an immutable one since it is never reassigned: replace
"let { path } = await params;" with a const binding (e.g., "const { path } =
await params;") in the GET function so the linter rule prefer-const is
satisfied; keep the subsequent use that builds filePath (filePath =
path?.join("/")... || "README.md") unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant